package com.sk.web;

import com.sk.util.FileUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.function.Consumer;

/**
 * 基于spring-web的常用工具类。
 *
 * @author smy
 */
@Slf4j
public class WebUtil {
    private static final String unknown = "unknown";
    private static final String localIp6 = "0:0:0:0:0:0:0:1";
    private static final String localIp4 = "127.0.0.1";
    private static final String[] agents = new String[]{
            "X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP",
            "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR"
    };

    public static HttpServletRequest getRequest() {
        ServletRequestAttributes attributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
        if (attributes == null) {
            return null;
        }
        return attributes.getRequest();
    }

    public static String getIp(HttpServletRequest request) {
        return getIp(request, agents);
    }

    public static String getIp(HttpServletRequest request, String[] agents) {
        // 获取请求主机IP地址,如果通过代理进来，则透过防火墙获取真实IP地址
        String ip = null;
        for (String key : agents) {
            ip = request.getHeader(key);
            if (checkIp(ip)) {
                break;
            }
        }
        if (StringUtils.hasText(ip)) {
            if (ip.contains(",")) {
                //通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
                String[] ips = ip.split(",");
                for (String s : ips) {
                    if (checkIp(s)) {
                        ip = s;
                        break;
                    }
                }
            }
        } else {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    public static boolean isLocalhost(String ip) {
        return localIp4.equals(ip) || localIp6.equals(ip);
    }


    public static boolean checkIp(String ip) {
        return StringUtils.hasText(ip) && !unknown.equalsIgnoreCase(ip);
    }


    @SneakyThrows
    public static void http302(HttpServletResponse response, String url) {
        response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
        response.setHeader("Location", url);
    }

    @SneakyThrows
    public static void download(HttpServletResponse response, String fileName, InputStream is) {
        download(response, fileName, os -> FileUtil.copyStream(is, os));
    }

    @SneakyThrows
    public static void download(HttpServletResponse response, String fileName, Consumer<OutputStream> cfe) {
        response.setContentType("application/octet-stream");
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        cfe.accept(response.getOutputStream());
    }

}
